home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 3 / CD ACTUAL 3.iso / linux / incoming / libgr-2.000 / libgr-2 / libgr-2.0.3 / tiff / tif_vms.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-08-20  |  13.2 KB  |  584 lines

  1. /* /usr/local/src/CVS/libgr/tiff/tif_vms.c,v 1.2 1995/08/20 12:51:33 neal Exp */
  2.  
  3. /*
  4.  * Copyright (c) 1988-1995 Sam Leffler
  5.  * Copyright (c) 1991-1995 Silicon Graphics, Inc.
  6.  *
  7.  * Permission to use, copy, modify, distribute, and sell this software and 
  8.  * its documentation for any purpose is hereby granted without fee, provided
  9.  * that (i) the above copyright notices and this permission notice appear in
  10.  * all copies of the software and related documentation, and (ii) the names of
  11.  * Sam Leffler and Silicon Graphics may not be used in any advertising or
  12.  * publicity relating to the software without the specific, prior written
  13.  * permission of Sam Leffler and Silicon Graphics.
  14.  * 
  15.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
  16.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
  17.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
  18.  * 
  19.  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
  20.  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  21.  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  22.  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
  23.  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
  24.  * OF THIS SOFTWARE.
  25.  */
  26.  
  27. /*
  28.  * TIFF Library VMS-specific Routines.
  29.  */
  30.  
  31. #include <stdlib.h>
  32. #include <unixio.h>
  33. #include "tiffiop.h"
  34. #if !HAVE_IEEEFP
  35. #include <math.h>
  36. #endif
  37.  
  38. #ifdef VAXC
  39. #define    NOSHARE    noshare
  40. #else
  41. #define    NOSHARE
  42. #endif
  43.  
  44. #ifdef __alpha
  45. /* Dummy entry point for backwards compatibility */
  46. void TIFFModeCCITTFax3(void){}
  47. #endif
  48.  
  49. static tsize_t
  50. _tiffReadProc(thandle_t fd, tdata_t buf, tsize_t size)
  51. {
  52.     return (read((int) fd, buf, size));
  53. }
  54.  
  55. static tsize_t
  56. _tiffWriteProc(thandle_t fd, tdata_t buf, tsize_t size)
  57. {
  58.     return (write((int) fd, buf, size));
  59. }
  60.  
  61. static toff_t
  62. _tiffSeekProc(thandle_t fd, toff_t off, int whence)
  63. {
  64.     return ((toff_t) lseek((int) fd, (off_t) off, whence));
  65. }
  66.  
  67. static int
  68. _tiffCloseProc(thandle_t fd)
  69. {
  70.     return (close((int) fd));
  71. }
  72.  
  73. #include <sys/stat.h>
  74.  
  75. static toff_t
  76. _tiffSizeProc(thandle_t fd)
  77. {
  78.     struct stat sb;
  79.     return (toff_t) (fstat((int) fd, &sb) < 0 ? 0 : sb.st_size);
  80. }
  81.  
  82. #ifdef HAVE_MMAP
  83. #include <starlet.h>
  84. #include <fab.h>
  85. #include <secdef.h>
  86.  
  87. /*
  88.  * Table for storing information on current open sections. 
  89.  * (Should really be a linked list)
  90.  */
  91. #define MAX_MAPPED 100
  92. static int no_mapped = 0;
  93. static struct {
  94.     char *base;
  95.     char *top;
  96.     unsigned short channel;
  97. } map_table[MAX_MAPPED];
  98.  
  99. /* 
  100.  * This routine maps a file into a private section. Note that this 
  101.  * method of accessing a file is by far the fastest under VMS.
  102.  * The routine may fail (i.e. return 0) for several reasons, for
  103.  * example:
  104.  * - There is no more room for storing the info on sections.
  105.  * - The process is out of open file quota, channels, ...
  106.  * - fd does not describe an opened file.
  107.  * - The file is already opened for write access by this process
  108.  *   or another process
  109.  * - There is no free "hole" in virtual memory that fits the
  110.  *   size of the file
  111.  */
  112. static int
  113. _tiffMapProc(thandle_t fd, tdata_t* pbase, toff_t* psize)
  114. {
  115.     char name[256];
  116.     struct FAB fab;
  117.     unsigned short channel;
  118.     char *inadr[2], *retadr[2];
  119.     unsigned long status;
  120.     long size;
  121.     
  122.     if (no_mapped >= MAX_MAPPED)
  123.         return(0);
  124.     /*
  125.      * We cannot use a file descriptor, we
  126.      * must open the file once more.
  127.      */
  128.     if (getname((int)fd, name, 1) == NULL)
  129.         return(0);
  130.     /* prepare the FAB for a user file open */
  131.     fab = cc$rms_fab;
  132.     fab.fab$l_fop |= FAB$V_UFO;
  133.     fab.fab$b_fac = FAB$M_GET;
  134.     fab.fab$b_shr = FAB$M_SHRGET;
  135.     fab.fab$l_fna = name;
  136.     fab.fab$b_fns = strlen(name);
  137.     status = sys$open(&fab);    /* open file & get channel number */
  138.     if ((status&1) == 0)
  139.         return(0);
  140.     channel = (unsigned short)fab.fab$l_stv;
  141.     inadr[0] = inadr[1] = (char *)0; /* just an address in P0 space */
  142.     /*
  143.      * Map the blocks of the file up to
  144.      * the EOF block into virtual memory.
  145.      */
  146.     size = _tiffSizeProc(fd);
  147.     status = sys$crmpsc(inadr, retadr, 0, SEC$M_EXPREG, 0,0,0, channel,
  148.         TIFFhowmany(size,512), 0,0,0);
  149.     if ((status&1) == 0){
  150.         sys$dassgn(channel);
  151.         return(0);
  152.     }
  153.     *pbase = (tdata_t) retadr[0];    /* starting virtual address */
  154.     /*
  155.      * Use the size of the file up to the
  156.      * EOF mark for UNIX compatibility.
  157.      */
  158.     *psize = (toff_t) size;
  159.     /* Record the section in the table */
  160.     map_table[no_mapped].base = retadr[0];
  161.     map_table[no_mapped].top = retadr[1];
  162.     map_table[no_mapped].channel = channel;
  163.     no_mapped++;
  164.  
  165.         return(1);
  166. }
  167.  
  168. /*
  169.  * This routine unmaps a section from the virtual address space of 
  170.  * the process, but only if the base was the one returned from a
  171.  * call to TIFFMapFileContents.
  172.  */
  173. static void
  174. _tiffUnmapProc(thandle_t fd, tdata_t base, toff_t size)
  175. {
  176.     char *inadr[2];
  177.     int i, j;
  178.     
  179.     /* Find the section in the table */
  180.     for (i = 0;i < no_mapped; i++) {
  181.         if (map_table[i].base == (char *) base) {
  182.             /* Unmap the section */
  183.             inadr[0] = (char *) base;
  184.             inadr[1] = map_table[i].top;
  185.             sys$deltva(inadr, 0, 0);
  186.             sys$dassgn(map_table[i].channel);
  187.             /* Remove this section from the list */
  188.             for (j = i+1; j < no_mapped; j++)
  189.                 map_table[j-1] = map_table[j];
  190.             no_mapped--;
  191.             return;
  192.         }
  193.     }
  194. }
  195. #else /* !HAVE_MMAP */
  196. static int
  197. _tiffMapProc(thandle_t fd, tdata_t* pbase, toff_t* psize)
  198. {
  199.     return (0);
  200. }
  201.  
  202. static void
  203. _tiffUnmapProc(thandle_t fd, tdata_t base, toff_t size)
  204. {
  205. }
  206. #endif /* !HAVE_MMAP */
  207.  
  208. /*
  209.  * Open a TIFF file descriptor for read/writing.
  210.  */
  211. TIFF*
  212. TIFFFdOpen(int fd, const char* name, const char* mode)
  213. {
  214.     TIFF* tif;
  215.  
  216.     tif = TIFFClientOpen(name, mode,
  217.         (thandle_t) fd,
  218.         _tiffReadProc, _tiffWriteProc, _tiffSeekProc, _tiffCloseProc,
  219.         _tiffSizeProc, _tiffMapProc, _tiffUnmapProc);
  220.     if (tif)
  221.         tif->tif_fd = fd;
  222.     return (tif);
  223. }
  224.  
  225. /*
  226.  * Open a TIFF file for read/writing.
  227.  */
  228. TIFF*
  229. TIFFOpen(const char* name, const char* mode)
  230. {
  231.     static const char module[] = "TIFFOpen";
  232.     int m, fd;
  233.  
  234.     m = _TIFFgetMode(mode, module);
  235.     if (m == -1)
  236.         return ((TIFF*)0);
  237.         if (m&O_TRUNC){
  238.                 /*
  239.          * There is a bug in open in VAXC. If you use
  240.          * open w/ m=O_RDWR|O_CREAT|O_TRUNC the
  241.          * wrong thing happens.  On the other hand
  242.          * creat does the right thing.
  243.                  */
  244.                 fd = creat((char *) /* bug in stdio.h */ name, 0666,
  245.             "alq = 128", "deq = 64", "mbc = 32",
  246.             "fop = tef");
  247.     } else if (m&O_RDWR) {
  248.         fd = open(name, m, 0666,
  249.             "deq = 64", "mbc = 32", "fop = tef", "ctx = stm");
  250.     } else
  251.         fd = open(name, m, 0666, "mbc = 32", "ctx = stm");
  252.     if (fd < 0) {
  253.         TIFFError(module, "%s: Cannot open", name);
  254.         return ((TIFF*)0);
  255.     }
  256.     return (TIFFFdOpen(fd, name, mode));
  257. }
  258.  
  259. tdata_t
  260. _TIFFmalloc(tsize_t s)
  261. {
  262.     return (malloc((size_t) s));
  263. }
  264.  
  265. void
  266. _TIFFfree(tdata_t p)
  267. {
  268.     free(p);
  269. }
  270.  
  271. tdata_t
  272. _TIFFrealloc(tdata_t p, tsize_t s)
  273. {
  274.     return (realloc(p, (size_t) s));
  275. }
  276.  
  277. void
  278. _TIFFmemset(tdata_t p, int v, tsize_t c)
  279. {
  280.     memset(p, v, (size_t) c);
  281. }
  282.  
  283. void
  284. _TIFFmemcpy(tdata_t d, const void* s, tsize_t c)
  285. {
  286.     memcpy(d, s, (size_t) c);
  287. }
  288.  
  289. int
  290. _TIFFmemcmp(const tdata_t p1, const tdata_t p2, tsize_t c)
  291. {
  292.     return (memcmp(p1, p2, (size_t) c));
  293. }
  294.  
  295. /*
  296.  * On the VAX, we need to make those global, writable pointers
  297.  * non-shareable, otherwise they would be made shareable by default.
  298.  * On the AXP, this brain damage has been corrected. 
  299.  * 
  300.  * I (Karsten Spang, krs@kampsax.dk) have dug around in the GCC
  301.  * manual and the GAS code and have come up with the following
  302.  * construct, but I don't have GCC on my VAX, so it is untested.
  303.  * Please tell me if it does not work.
  304.  */
  305.  
  306. static void
  307. vmsWarningHandler(const char* module, const char* fmt, va_list ap)
  308. {
  309.     if (module != NULL)
  310.         fprintf(stderr, "%s: ", module);
  311.     fprintf(stderr, "Warning, ");
  312.     vfprintf(stderr, fmt, ap);
  313.     fprintf(stderr, ".\n");
  314. }
  315.  
  316. NOSHARE TIFFErrorHandler _TIFFwarningHandler = vmsWarningHandler
  317. #if defined(VAX) && defined(__GNUC__)
  318. asm("_$$PsectAttributes_NOSHR$$_TIFFwarningHandler")
  319. #endif
  320. ;
  321.  
  322. static void
  323. vmsErrorHandler(const char* module, const char* fmt, va_list ap)
  324. {
  325.     if (module != NULL)
  326.         fprintf(stderr, "%s: ", module);
  327.     vfprintf(stderr, fmt, ap);
  328.     fprintf(stderr, ".\n");
  329. }
  330.  
  331. NOSHARE TIFFErrorHandler _TIFFerrorHandler = vmsErrorHandler
  332. #if defined(VAX) && defined(__GNUC__)
  333. asm("_$$PsectAttributes_NOSHR$$_TIFFerrorHandler")
  334. #endif
  335. ;
  336.  
  337.  
  338. #if !HAVE_IEEEFP
  339. /* IEEE floting point handling */
  340.  
  341. typedef    struct ieeedouble {
  342.     u_long    mant    : 20,
  343.         exp    : 11,
  344.         sign    : 1;
  345.     u_long    mant2;
  346. } ieeedouble;
  347. typedef    struct ieeefloat {
  348.     u_long    mant    : 23,
  349.         exp    : 8,
  350.         sign    : 1;
  351. } ieeefloat;
  352.  
  353. typedef    struct {
  354.     u_long    mant1    : 7,
  355.         exp    : 8,
  356.         sign    : 1,
  357.         mant2    : 16,
  358.         mant3   : 16,
  359.         mant4   : 16;
  360. } nativedouble;
  361. typedef    struct {
  362.     u_long    mant1    : 7,
  363.         exp    : 8,
  364.         sign    : 1,
  365.         mant2    : 16;
  366. } nativefloat;
  367.  
  368. typedef    union {
  369.     ieeedouble    ieee;
  370.     nativedouble    native;
  371.     char        b[8];
  372.     uint32        l[2];
  373.     double        d;
  374. } double_t;
  375.  
  376. typedef    union {
  377.     ieeefloat    ieee;
  378.     nativefloat    native;
  379.     char        b[4];
  380.     uint32        l;
  381.     float        f;
  382. } float_t;
  383.  
  384. #if defined(VAXC) || defined(DECC)
  385. #pragma inline(ieeetod,dtoieee)
  386. #endif
  387.  
  388. /*
  389.  * Convert an IEEE double precision number to native double precision.
  390.  * The source is contained in two longwords, the second holding the sign,
  391.  * exponent and the higher order bits of the mantissa, and the first
  392.  * holding the rest of the mantissa as follows:
  393.  * (Note: It is assumed that the number has been eight-byte swapped to
  394.  * LSB first.)
  395.  * 
  396.  * First longword:
  397.  *    32 least significant bits of mantissa
  398.  * Second longword:
  399.  *    0-19:    20 most significant bits of mantissa
  400.  *    20-30:    exponent
  401.  *    31:    sign
  402.  * The exponent is stored as excess 1023.
  403.  * The most significant bit of the mantissa is implied 1, and not stored.
  404.  * If the exponent and mantissa are zero, the number is zero.
  405.  * If the exponent is 0 (i.e. -1023) and the mantissa is non-zero, it is an
  406.  * unnormalized number with the most significant bit NOT implied.
  407.  * If the exponent is 2047, the number is invalid, in case the mantissa is zero,
  408.  * this means overflow (+/- depending of the sign bit), otherwise
  409.  * it simply means invalid number.
  410.  * 
  411.  * If the number is too large for the machine or was specified as overflow, 
  412.  * +/-HUGE_VAL is returned.
  413.  */
  414. INLINE static void
  415. ieeetod(double *dp)
  416. {
  417.     double_t source;
  418.     long sign,exp,mant;
  419.     double dmant;
  420.  
  421.     source.d = *dp;
  422.     sign = source.ieee.sign;
  423.     exp = source.ieee.exp;
  424.     mant = source.ieee.mant;
  425.  
  426.     if (exp == 2047) {
  427.         if (mant)            /* Not a Number (NAN) */
  428.             *dp = HUGE_VAL;
  429.         else                /* +/- infinity */
  430.             *dp = (sign ? -HUGE_VAL : HUGE_VAL);
  431.         return;
  432.     }
  433.     if (!exp) {
  434.         if (!(mant || source.ieee.mant2)) {    /* zero */
  435.             *dp=0;
  436.             return;
  437.         } else {            /* Unnormalized number */
  438.             /* NB: not -1023, the 1 bit is not implied */
  439.             exp= -1022;
  440.         }
  441.     } else {
  442.         mant |= 1<<20;
  443.         exp -= 1023;
  444.     }
  445.     dmant = (((double) mant) +
  446.         ((double) source.ieee.mant2) / (((double) (1<<16)) *
  447.         ((double) (1<<16)))) / (double) (1<<20);
  448.     dmant = ldexp(dmant, exp);
  449.     if (sign)
  450.         dmant= -dmant;
  451.     *dp = dmant;
  452. }
  453.  
  454. INLINE static void
  455. dtoieee(double *dp)
  456. {
  457.     double_t num;
  458.     double x;
  459.     int exp;
  460.  
  461.     num.d = *dp;
  462.     if (!num.d) {            /* Zero is just binary all zeros */
  463.         num.l[0] = num.l[1] = 0;
  464.         return;
  465.     }
  466.  
  467.     if (num.d < 0) {        /* Sign is encoded separately */
  468.         num.d = -num.d;
  469.         num.ieee.sign = 1;
  470.     } else {
  471.         num.ieee.sign = 0;
  472.     }
  473.  
  474.     /* Now separate the absolute value into mantissa and exponent */
  475.     x = frexp(num.d, &exp);
  476.  
  477.     /*
  478.      * Handle cases where the value is outside the
  479.      * range for IEEE floating point numbers. 
  480.      * (Overflow cannot happen on a VAX, but underflow
  481.      * can happen for G float.)
  482.      */
  483.     if (exp < -1022) {        /* Unnormalized number */
  484.         x = ldexp(x, -1023-exp);
  485.         exp = 0;
  486.     } else if (exp > 1023) {    /* +/- infinity */
  487.         x = 0;
  488.         exp = 2047;
  489.     } else {            /* Get rid of most significant bit */
  490.         x *= 2;
  491.         x -= 1;
  492.         exp += 1023;
  493.     }
  494.     num.ieee.exp = exp;
  495.  
  496.     x *= (double) (1<<20);
  497.     num.ieee.mant = (long) x;
  498.     x -= (double) num.ieee.mant;
  499.     num.ieee.mant2 = (long) (x*((double) (1<<16)*(double) (1<<16)));
  500.  
  501.     if (!(num.ieee.mant || num.ieee.exp || num.ieee.mant2)) {
  502.         /* Avoid negative zero */
  503.         num.ieee.sign = 0;
  504.     }
  505.     *dp = num.d;
  506. }
  507.  
  508. /*
  509.  * Beware, these do not handle over/under-flow
  510.  * during conversion from ieee to native format.
  511.  */
  512. #define    NATIVE2IEEEFLOAT(fp) { \
  513.     float_t t; \
  514.     if (t.ieee.exp = (fp)->native.exp) \
  515.     t.ieee.exp += -129 + 127; \
  516.     t.ieee.sign = (fp)->native.sign; \
  517.     t.ieee.mant = ((fp)->native.mant1<<16)|(fp)->native.mant2; \
  518.     *(fp) = t; \
  519. }
  520. #define    IEEEFLOAT2NATIVE(fp) { \
  521.     float_t t; int v = (fp)->ieee.exp; \
  522.     if (v) v += -127 + 129;        /* alter bias of exponent */\
  523.     t.native.exp = v;            /* implicit truncation of exponent */\
  524.     t.native.sign = (fp)->ieee.sign; \
  525.     v = (fp)->ieee.mant; \
  526.     t.native.mant1 = v >> 16; \
  527.     t.native.mant2 = v;\
  528.     *(fp) = t; \
  529. }
  530.  
  531. #define IEEEDOUBLE2NATIVE(dp) ieeetod(dp)
  532.  
  533. #define NATIVE2IEEEDOUBLE(dp) dtoieee(dp)
  534.  
  535.  
  536. /*
  537.  * These unions are used during floating point
  538.  * conversions.  The above macros define the
  539.  * conversion operations.
  540.  */
  541. void
  542. TIFFCvtIEEEFloatToNative(TIFF* tif, u_int n, float* f)
  543. {
  544.     float_t* fp = (float_t*) f;
  545.  
  546.     while (n-- > 0) {
  547.         IEEEFLOAT2NATIVE(fp);
  548.         fp++;
  549.     }
  550. }
  551.  
  552. void
  553. TIFFCvtNativeToIEEEFloat(TIFF* tif, u_int n, float* f)
  554. {
  555.     float_t* fp = (float_t*) f;
  556.  
  557.     while (n-- > 0) {
  558.         NATIVE2IEEEFLOAT(fp);
  559.         fp++;
  560.     }
  561. }
  562. void
  563. TIFFCvtIEEEDoubleToNative(TIFF* tif, u_int n, float* f)
  564. {
  565.     float_t* fp = (float_t*) f;
  566.  
  567.     while (n-- > 0) {
  568.         IEEEDOUBLE2NATIVE(fp);
  569.         fp++;
  570.     }
  571. }
  572.  
  573. void
  574. TIFFCvtNativeToIEEEDouble(TIFF* tif, u_int n, float* f)
  575. {
  576.     float_t* fp = (float_t*) f;
  577.  
  578.     while (n-- > 0) {
  579.         NATIVE2IEEEDOUBLE(fp);
  580.         fp++;
  581.     }
  582. }
  583. #endif
  584.